#include "levelbrowser.h"
#include "buttonitem.h"
#include "levelitem.h"
#include "level.h"
#include "point.h"
#include "line.h"

LevelBrowser::LevelBrowser(QGraphicsItem *parent, QGraphicsScene *scene) :
    QGraphicsItem(parent, scene), currentPage(0), type(DEFAULT)
{
    initScene();
    initEventSystem();

    positionMap[0] = QPoint(65, 51);
    positionMap[1] = QPoint(313, 51);
    positionMap[2] = QPoint(561, 51);
    positionMap[3] = QPoint(65, 239);
    positionMap[4] = QPoint(313, 239);
    positionMap[5] = QPoint(561, 239);
}

void LevelBrowser::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{

}

QRectF LevelBrowser::boundingRect() const
{
    return scene()->sceneRect();
}

void LevelBrowser::initScene()
{

    background = new ImageItem(":/selector-background", QPoint(),
                               QPoint(ImageItem::BG_SIZE.width(),
                                      ImageItem::BG_SIZE.height()),
                               scene(), NULL);

    returnBg = new ButtonItem(":/editor-return", QPoint(69, 477),
                             QPoint(116, 521), scene(), background);

    prevButton = new ButtonItem(":/dialog-prev", QPoint(190, 470),
                                QPoint(246, 516), scene(), background);

    nextButton = new ButtonItem(":/dialog-next", QPoint(652, 476),
                                QPoint(714, 525), scene(), background);
}

void LevelBrowser::initEventSystem()
{
    connect(returnBg, SIGNAL(clicked(ButtonItem*)), this, SLOT(clicked(ButtonItem*)));
    connect(prevButton, SIGNAL(clicked(ButtonItem*)), this, SLOT(clicked(ButtonItem*)));
    connect(nextButton, SIGNAL(clicked(ButtonItem*)), this, SLOT(clicked(ButtonItem*)));

}

void LevelBrowser::clear()
{    while (!displayLevelBgs.isEmpty()) {
        ImageItem* i = displayLevelBgs.first();
        displayLevelBgs.removeFirst();
        delete i;
    }

     // When a parent is deleted, all its children will be deleted too.
     // Strange!

//    while (!displayLevels.isEmpty()) {
//        Level* l = displayLevels.first();
//        displayLevels.removeFirst();
//        delete l;
//    }
     displayLevels.clear();
}

void LevelBrowser::setDisplayLevels(const QLinkedList<Level*> &levels)
{
    clear();

    QLinkedList<Level*>::const_iterator it;
    int i;
    for (it=levels.begin(), i=0; it!=levels.end(); it++, i++)
    {
        QPoint bgPos = positionMap[i%6];
        LevelItem *bg = new LevelItem(":/dialog-level", bgPos, bgPos+QPoint(168, 128),
                                      scene(), background);
        connect(bg, SIGNAL(clicked(LevelItem*)), this, SLOT(levelSelected(LevelItem*)));
        QGraphicsTextItem* banner = new QGraphicsTextItem((*it)->getName(), bg, scene());
        banner->setFont(QFont("Janis", 10));
        banner->setPos(60, 8);
        banner->setDefaultTextColor(Qt::red);
        if ((*it)->isLocked() && type==LOAD)
        {
            new ImageItem(":/dialog-lock", QPoint(107, 67),
                                            QPoint(168, 128), scene(), bg);
        }
        Level *level = new Level((*it)->getId(), (*it)->getName());
        level->setLocked((*it)->isLocked());
        QHash<Point*, Point*> convertMap;
        QLinkedList<Point*> pl = (*it)->getPointsList();
        QLinkedList<Line*> ll = (*it)->getLinesList();

        QLinkedList<Point *>::const_iterator pit;
        for (pit=pl.begin(); pit!=pl.end(); pit++) {
            Point* p = new Point(((*pit)->rect().center()+QPointF(80, 105))/4.5, bg, scene(), 3);
            p->setEnabled(false);
            p->setAcceptHoverEvents(false);
            convertMap[*pit] = p;
            level->addPoint(p);
        }

        QLinkedList<Line *>::const_iterator lit;
        for (lit=ll.begin(); lit!=ll.end(); lit++) {
            Line* l = new Line(convertMap[(*lit)->getStartPoint()], bg, scene(), 1);
            l->setColor((*lit)->getColor());
            l->setEnabled(false);
            l->setAcceptHoverEvents(false);
            if ((*lit)->getEndPoint() != NULL)
                l->setEndPoint(convertMap[(*lit)->getEndPoint()]);
            level->addLine(l);
        }
        displayLevels.push_back(level);
        displayLevelBgs.push_back(bg);
    }
    currentPage = 0;
    updatePage();
}

void LevelBrowser::clicked(ButtonItem *who)
{
    if (returnBg == who)
        emit returnClicked();
    else if (prevButton == who)
        prevPage();
    else if (nextButton == who)
        nextPage();
}

void LevelBrowser::levelSelected(LevelItem *who)
{
    QLinkedList<LevelItem*>::iterator liit;
    QLinkedList<Level*>::iterator lit;
    int id = -1;
    for (liit=displayLevelBgs.begin(), lit=displayLevels.begin();
         liit!=displayLevelBgs.end(), lit!=displayLevels.end();
         liit++, lit++)
    {
        if (who == *liit)
        {
            id = (*lit)->getId();
            break;
        }
    }

//    qDebug() << type;
//    qDebug() << (*lit)->isLocked();
    if ((*lit)->isLocked() && type==LOAD)
//    {
//        qDebug() << "got";
        return;
//    }
//    qDebug() << "over";
    emit levelSelected(id);
}

void LevelBrowser::updatePage()
{
    QLinkedList<LevelItem*>::iterator it;

    int i;
    for (it=displayLevelBgs.begin(), i=0; it!=displayLevelBgs.end(); it++, i++)
    {
        LevelItem* level = *it;
        if (i/6 == currentPage)
            level->setVisible(true);
        else level->setVisible(false);
    }
}

void LevelBrowser::prevPage()
{
    if (currentPage == 0)
        return;
    currentPage--;
    updatePage();
}

void LevelBrowser::nextPage()
{
    if (currentPage == displayLevelBgs.size()/6)
        return;
    currentPage ++;
    updatePage();
}

